﻿using Abp;
using Abp.Dependency;
using Abp.Domain.Repositories;
using Abp.UI;
using Mt.Organizations;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Mt.Site.Core.Organizations.Posts
{
    public class PostManager :MtSiteDomainServiceBase, IPostManager, ITransientDependency
    {
        private readonly IRepository<Post, long> _postRepository;
        private readonly IRepository<PostOrganization, long> _postOrganizationRepository;
        private readonly IRepository<UserPost, long> _userPostRepository;

        public IQueryable<Post> Post => _postRepository.GetAll();
        public IQueryable<PostOrganization> PostOrganizationUnit => _postOrganizationRepository.GetAll();

        public PostManager(
            IRepository<Post, long> postRepository,
            IRepository<PostOrganization, long> postOrganizationRepository,
            IRepository<UserPost, long> userPostRepository)
        {
            _postRepository = postRepository;
            _postOrganizationRepository = postOrganizationRepository;
            _userPostRepository = userPostRepository;
        }

        public async Task CreateOrUpdateAsync(Post post, IList<long> unitIds, IList<long> userIds)
        {
            if (post.Id > 0)
            {
                await ValidateItemAsync(post);
                await _postRepository.UpdateAsync(post);
                await SetPostOrganizationsAsync(unitIds, post.Id);
                await SetPostUsersAsync(userIds, post.Id);
            }
            else
            {
                await ValidateItemAsync(post);
                await _postRepository.InsertAsync(post);

                await CurrentUnitOfWork.SaveChangesAsync();

                await SetPostOrganizationsAsync(unitIds, post.Id);
                await SetPostUsersAsync(userIds, post.Id);
            }
        }

        public async Task DeleteAsync(Post post)
        {
            //职务数据的删除， 部门删除时，需要删除职务 ，进而删除关系数据
            if (post.Id > 0)
            {
                await _userPostRepository.DeleteAsync(c => c.PostId == post.Id);
                await _postOrganizationRepository.DeleteAsync(c => c.PostId == post.Id);
                await _postRepository.DeleteAsync(post);
            }
        }

        public async Task DeleteAsync(long postId)
        {
           var item = await _postRepository.FirstOrDefaultAsync(c => c.Id == postId);
            if(item != null)
            {
                await DeleteAsync(item);
            }
        }

        public async Task<List<Post>> GetAllListAsync(long unitId)
        {
             return await _postRepository.GetAllListAsync(c=>c.OrganizationId == unitId);
        }

        public async Task<List<long>> GetPostOrganizationListAsync(long postId)
        {
            var items = await _postOrganizationRepository.GetAllListAsync(c => c.PostId == postId);
            return items.Select(c => c.OrganizationId).ToList();
        }
        public async Task<List<long>> GetPostUserListAsync(long postId)
        {
            var items = await _userPostRepository.GetAllListAsync(c => c.PostId == postId);
            return items.Select(c => c.UserId).ToList();
        }

        private async Task SetPostOrganizationsAsync(IList<long> newUnits, long postId)
        {
            var oldUnits = await GetPostOrganizationListAsync(postId);

            var IdList = oldUnits.Where(p => !newUnits.Contains(p));
            await _postOrganizationRepository.DeleteAsync(c => IdList.Contains(c.OrganizationId) && c.PostId == postId);

            IdList = newUnits.Where(p => !oldUnits.Contains(p));

            foreach (var unitId in IdList)
            {
                await _postOrganizationRepository.InsertAsync(new PostOrganization { OrganizationId = unitId, PostId = postId });
            }
        }
        private async Task SetPostUsersAsync(IList<long> newUserIds, long postId)
        {
            var oldUserIds = await GetPostUserListAsync(postId);

            var IdList = oldUserIds.Where(p => !newUserIds.Contains(p));
            await _userPostRepository.DeleteAsync(c => IdList.Contains(c.UserId) && c.PostId == postId);

            IdList = newUserIds.Where(p => !oldUserIds.Contains(p));

            foreach (var userId in IdList)
            {
                await _userPostRepository.InsertAsync(new UserPost { UserId = userId, PostId = postId });
            }
        }

        private async Task ValidateItemAsync(Post post)
        {
            if ((await _postRepository.FirstOrDefaultAsync(m => m.DisplayName == post.DisplayName && m.Id != post.Id)) != null)
            {
                throw new UserFriendlyException($"职务名{post.DisplayName}已存在");
            }
        }

        public List<NameValue<int>> GetRoles()
        {
            var list = EnumHelper.GetEnumList<PostGroup>();

            return list.OrderByDescending(c => c.Value).ToList();
        }
    }
}
